package com.chenfan.process.pattern.template;

import com.chenfan.ccp.common.exception.ApiException;
import com.chenfan.ccp.util.tool.UuidUtil;
import com.chenfan.process.common.exception.ProcessResultCode;
import com.chenfan.process.entity.dto.ApprovalUserDTO;
import com.chenfan.process.entity.dto.DetailAndProcessInstanceDTO;
import com.chenfan.process.entity.po.ProcessDetailPo;
import com.chenfan.process.entity.po.ProcessInstanceApprovePo;
import com.chenfan.process.entity.po.ProcessPo;
import com.chenfan.process.entity.po.ProcessRelatedPo;
import com.chenfan.process.enums.ProcessResultTypeEnums;
import com.chenfan.process.util.ProcessUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

/**
 * @author K
 * @date 2022/7/11 4:12 PM
 */
@Component
@Scope("prototype")
public class SimpleNodeHandler extends AbstractNodeHandler {

    @Override
    public boolean processBefore() {
        return updateBefore();
    }

    @Override
    public DetailAndProcessInstanceDTO generateForCurrent() {
        return generateCurrent();
    }

    @Override
    public DetailAndProcessInstanceDTO getDetailAndProcessInstances() {
        ProcessRelatedPo processRelatedPo = processRelatedPoList.get(0);
        Long processAfterId = processRelatedPo.getProcessAfterId();
        ProcessPo processPo = null;
        if (!startEvent) {
            processPo = instanceSnapshotDTO.findByProcessId(processAfterId);
        } else {
            processPo = processService.getById(processAfterId);

        }

        ProcessDetailPo processDetail = ProcessDetailPo.builder().processId(processRelatedPo.getProcessBeforeId())
                .nextProcessId(processRelatedPo.getProcessAfterId()).approvalTemplateId(processRelatedPo.getApprovalTemplateId())
                .parentId(approvalPo.getApprovalId())
                .resultType(ProcessResultTypeEnums.CREATED.getIndex())
                .build();
        processDetail.setId(UuidUtil.generateId());

        relatedList.add(processRelatedPo);

        // 部门负责人
        if (ProcessUtil.department(processPo.getAssociateGroupId())) {
            ApprovalUserDTO user = processDepartHead();

            // 无部门负责人
            if (Objects.isNull(user)) {
                noDepartmentHeader = true;
                return noDepartment();
            }
            // 有部门负责人
            List<ProcessInstanceApprovePo> processInstanceList = department(user.getUserId(), user.getUserName(), processDetail.getId());
            return DetailAndProcessInstanceDTO.builder()
                    .processInstanceList(processInstanceList)
                    .processDetail(processDetail).build();
        }

        // 自选人
        if (ProcessUtil.optional(processPo.getAssociateGroupId())) {
            Long nextUserId = approvalDTO.getNextUserId();
            String nextUserName = approvalDTO.getNextUserName();
            if (Objects.isNull(nextUserId) || StringUtils.isEmpty(nextUserName)) {
                throw new ApiException(ProcessResultCode.NOT_SPECIFIC_NODE);
            }

            List<ProcessInstanceApprovePo> processInstanceList = optional(nextUserId, nextUserName, processDetail.getId());
            return DetailAndProcessInstanceDTO.builder()
                    .processInstanceList(processInstanceList)
                    .processDetail(processDetail).build();
        }

        // 创建人
        if (processPo.isApproval()) {
            List<ProcessInstanceApprovePo> processInstanceList = individual(approvalPo.getCreateBy(), approvalPo.getCreateName(), processDetail.getId());
            return DetailAndProcessInstanceDTO.builder()
                    .processInstanceList(processInstanceList)
                    .processDetail(processDetail).build();
        }

        // 普通情况
        List<ProcessInstanceApprovePo> processInstanceList = individual(Long.valueOf(processPo.getAssociateGroupId()), processPo.getAssociateGroupName(), processDetail.getId());
        return DetailAndProcessInstanceDTO.builder()
                .processInstanceList(processInstanceList)
                .processDetail(processDetail).build();
    }
}
